﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Lesson01_同步_服务端_Exercises1
{
    class Program
    {
        static bool isClose = false;
        static Socket socketTcp;
        //存储客户端连接
        static List<Socket> clientSocketList = new List<Socket>();
        static void Main(string[] args)
        {
            //1.建立Socket 绑定监听
            socketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080);
                socketTcp.Bind(ipPoint);
            }
            catch (Exception e)
            {
                Console.WriteLine("绑定报错:" + e.Message);
                return;
            }
            socketTcp.Listen(1024);
            //2.等待客户端连接(特别处理)
            Thread acceptThread = new Thread(AcceptClientConnect);
            acceptThread.Start();
            //3.收发消息(特别处理)
            Thread recvThread = new Thread(RecvMsg);
            recvThread.Start();

            //4.关闭相关
            while (true)
            {
                string input = Console.ReadLine();
                //关闭所有连接
                if (input == "Quit")
                {
                    isClose = true;
                    for (int i = 0; i < clientSocketList.Count; i++)
                    {
                        clientSocketList[i].Shutdown(SocketShutdown.Both);
                        clientSocketList[i].Close();
                    }
                    clientSocketList.Clear();
                }
                //广播消息
                else if(input.Substring(0,2) == "B:")
                {
                    for (int i = 0; i < clientSocketList.Count; i++)
                    {
                        clientSocketList[i].Send(Encoding.UTF8.GetBytes(input.Substring(2, input.Length)));
                    }
                }
            }

        }

        static void AcceptClientConnect()
        {
            while(!isClose)
            {
                Console.WriteLine("开始监听连接...");
                Socket clientSockt = socketTcp.Accept();
                clientSockt.Send(Encoding.UTF8.GetBytes("欢迎来到三体世界!"));
                Console.WriteLine("客户端[{0}]连接...", clientSockt.RemoteEndPoint.ToString());
                clientSocketList.Add(clientSockt);
                
            }
        }
        static void RecvMsg()
        {
            Socket clientSocket;
            int recvLen;
            byte[] receBytes = new byte[1024 * 1024];
            int i;
            while (!isClose)
            {
                for(i=0; i< clientSocketList.Count; i++)
                {
                    clientSocket = clientSocketList[i];
                    if(clientSocket.Available > 0)
                    {
                        recvLen = clientSocket.Receive(receBytes);
                        //为了不影响其它客户端 把消息处理 交给新的线程 为了节约线程相关的开销 使用线程池
                        ThreadPool.QueueUserWorkItem(HandleMsg, (clientSocket, Encoding.UTF8.GetString(receBytes, 0, recvLen)));
                    }
                }
            }
        }

        static void HandleMsg(object obj)
        {
            (Socket s, string str) info = ((Socket s, string str))obj;
            Console.WriteLine("收到客户端{0} 发来的消息:{1}", info.s.RemoteEndPoint.ToString(), info.str);
        }
    }
}